﻿using FluentAssertions;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Linq;
using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling;

namespace NewRetail.Application.Core.Entity
{
    public static class BaseEntityExtension
    {
        public static EntityTypeBuilder<T> ConfigReceiptEntity<T>(this EntityTypeBuilder<T> builder) where T : class, IReceiptEntity
        {
            builder.Property(x => x.receiptNo).HasMaxLength(100).IsRequired();
            builder.Property(x => x.receiptDate).IsRequired().HasColumnType("datetime");
            builder.Property(x => x.isAuditing);
            builder.Property(x => x.receiptNo).IsRequired().HasMaxLength(50);
            builder.Property(x => x.receiptDate).IsRequired().HasColumnType("datetime");
            builder.Property(x => x.operateUserID);
            builder.Property(x => x.operateTime).HasColumnType("datetime");
            builder.Property(x => x.remark).HasMaxLength(500);

            return builder;
        }

        public static EntityTypeBuilder<T> ConfigBaseEntity<T>(this EntityTypeBuilder<T> builder) where T : BaseEntity
        {
            builder.HasKey(x => x.Id);
            builder.Property(x => x.Id).HasMaxLength(50).HasColumnName("id");

            builder.Property(x => x.addTime).HasColumnType("datetime");
            builder.Property(x => x.updateTime).HasColumnType("datetime");

            builder.Ignore(x => x._IdForSerialize);

            if (typeof(T).IsAssignableTo<ISoftDelete>())
            {
                var m = typeof(BaseEntityExtension)
                    .GetMethods(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static)
                    .FirstOrDefault(x => x.Name == nameof(FilterSoftDeleted));

                m.Should().NotBeNull();

                m.MakeGenericMethod(typeof(T)).Invoke(obj: null, parameters: new[] { builder });
            }

            return builder;
        }

        public static void FilterSoftDeleted<T>(EntityTypeBuilder<T> builder) where T : class, ISoftDelete
        {
            builder.ConfigureSoftDelete();
            builder.HasQueryFilter(x => !x.IsDeleted);
        }

        public static EntityTypeBuilder<T> ConfigNo<T>(this EntityTypeBuilder<T> builder) where T : BaseEntityWithNo
        {
            builder.Property(x => x.No).IsRequired().HasMaxLength(100);
            builder.HasIndex(x => x.No).IsUnique();

            return builder;
        }

        public static EntityTypeBuilder<T> ConfigWarehouse<T>(this EntityTypeBuilder<T> builder) where T : class, IWarehouseEntity
        {
            builder.Property(x => x.warehouseID).HasMaxLength(100);

            return builder;
        }
    }
}
